import {
  AutoComplete,
  Button,
  Col,
  Form,
  Icon,
  Input,
  message,
  Radio,
  Row,
  Select,
  Spin,
  Switch,
  Tabs,
  Tooltip,
} from 'antd';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import request from '@/utils/request';
import DynamicHttpHeaders, { clipboardTextHeaderValues } from '@/components/DynamicHttpHeaders';
import { hasMoreThanOne } from '@/utils/utils';
import HttpCallUrlInput from './components/HttpCallUrlInput';
import CustomHandlerSelector from '@/components/CustomHandlerSelector';
import Space from '@/components/Space';

const { TabPane } = Tabs;
const { TextArea } = Input;

const SmallFormItemLayout = {
  labelCol: { span: 3 },
  wrapperCol: { span: 9 },
};

const FormItemLayout = {
  labelCol: { span: 6 },
  wrapperCol: { span: 18 },
};

function HttpCallEditor({
  httpCallId,
  versionId,
  form,
  readOnly = false,
  onCancel,
  onSaveAndValidVersion,
}) {
  const { getFieldDecorator, getFieldValue, setFieldsValue, validateFields } = form;

  const [loading, setLoading] = useState(true);

  const [httpHeaders, setHttpHeaders] = useState([]);
  const headersRef = useRef(null);

  useEffect(() => {
    request
      .get(`/httpCall/queryVersionData?versionId=${versionId}`)
      .then(data => {
        if (data) {
          const requestHeaders = data.requestHeaders ? JSON.parse(data.requestHeaders) : [];
          const mockResponse = hasMoreThanOne(data.mocks) ? data.mocks[0].responseBody : undefined;
          setFieldsValue({
            ...data,
            isMock: data.isMock === 1,
            replaceResponseHeaders: data.replaceResponseHeaders === 1,
            appendResponseHeaders: data.appendResponseHeaders === 1,
            replaceResponseStatus: data.replaceResponseStatus === 1,
            mockResponse,
            interceptor: { className: data.interceptorClassName, params: data.interceptorParams },
          });
          setHttpHeaders(requestHeaders);
        }
      })
      .finally(() => setLoading(false));
  }, [setFieldsValue, versionId]);

  const getFormData = useCallback(
    fieldsValue => {
      let data = {
        ...fieldsValue,
        requestHeaders: httpHeaders ? JSON.stringify(httpHeaders) : '[]',
        isMock: fieldsValue.isMock ? 1 : 0,
        replaceResponseHeaders: fieldsValue.replaceResponseHeaders ? 1 : 0,
        appendResponseHeaders: fieldsValue.appendResponseHeaders ? 1 : 0,
        replaceResponseStatus: fieldsValue.replaceResponseStatus ? 1 : 0,
        versionId,
        mocks: fieldsValue.mockResponse ? [{ responseBody: fieldsValue.mockResponse }] : [],
      };
      if (fieldsValue.interceptor) {
        data = {
          ...data,
          interceptorClassName: fieldsValue.interceptor.className,
          interceptorParams: fieldsValue.interceptor.params,
        };
      }
      return data;
    },
    [httpHeaders, versionId]
  );

  /**
   * 提交表单
   */
  const save = useCallback(() => {
    validateFields((err, fieldsValue) => {
      if (!err) {
        const data = getFormData(fieldsValue);
        setLoading(true);
        request
          .post('/httpCall/saveVersionData', { data })
          .then(() => {
            message.success('保存成功');
            onCancel();
          })
          .finally(() => {
            setLoading(false);
          });
      }
    });
  }, [getFormData, onCancel, validateFields]);

  /**
   * 保存并提交
   */
  const saveAndValid = useCallback(() => {
    validateFields((err, fieldsValue) => {
      if (!err) {
        let data = getFormData(fieldsValue);
        data = {
          ...data,
          httpCallId,
        };
        setLoading(true);
        request
          .post('/httpCall/saveAndValidVersion', { data })
          .then(() => {
            message.success('保存并生效成功');
            onCancel();
            onSaveAndValidVersion && onSaveAndValidVersion();
          })
          .finally(() => {
            setLoading(false);
          });
      }
    });
  }, [getFormData, httpCallId, onCancel, onSaveAndValidVersion, validateFields]);

  function renderFooter() {
    if (readOnly) {
      return null;
    }
    return (
      <div className="modal-footer">
        <Space className="pull-right">
          <Button style={{ marginRight: 8 }} onClick={onCancel}>
            取消
          </Button>
          <Button type="primary" onClick={save} loading={loading}>
            保存
          </Button>
          <Button type="primary" onClick={saveAndValid} loading={loading}>
            保存并生效
          </Button>
        </Space>
      </div>
    );
  }

  return (
    <>
      <Spin spinning={loading}>
        <Form layout="horizontal" id="tg_httpCallEditorForm">
          <div style={{ display: 'flex' }}>
            <Form.Item>{getFieldDecorator('configId')(<Input hidden />)}</Form.Item>
            <Form.Item style={{ flex: 'none' }}>
              {getFieldDecorator('requestMethod', {
                initialValue: 'POST',
                rules: [
                  {
                    required: true,
                  },
                ],
              })(
                <Select placeholder="--请选择--" style={{ width: '90px' }}>
                  <Select.Option key="POST" value="POST">
                    POST
                  </Select.Option>
                  <Select.Option key="GET" value="GET">
                    GET
                  </Select.Option>
                  <Select.Option key="PUT" value="PUT">
                    PUT
                  </Select.Option>
                  <Select.Option key="PATCH" value="PATCH">
                    PATCH
                  </Select.Option>
                  <Select.Option key="DELETE" value="DELETE">
                    DELETE
                  </Select.Option>
                </Select>
              )}
            </Form.Item>
            <Form.Item style={{ flex: 1 }}>
              {getFieldDecorator('requestUrl', {
                rules: [
                  {
                    required: true,
                    message: '接口地址不能为空',
                  },
                ],
              })(<HttpCallUrlInput />)}
            </Form.Item>
          </div>
          <div className="ant-detail-title">请求参数</div>
          <Tabs defaultActiveKey="body">
            <TabPane tab="Body" key="body">
              <Form.Item
                label="格式"
                {...{
                  labelCol: { span: 3 },
                  wrapperCol: { span: 21 },
                }}
              >
                {getFieldDecorator('requestBodyFormat', {
                  initialValue: 'JSON',
                  rules: [
                    {
                      required: true,
                      message: '格式不能为空',
                    },
                  ],
                })(
                  <Radio.Group>
                    <Radio value="JSON">JSON</Radio>
                    <Radio value="XML">XML</Radio>
                    <Radio value="NONE">普通文本</Radio>
                    <Radio value="FORM_DATA">form-data</Radio>
                    <Radio value="FORM_URLENCODED">x-www-form-urlencoded</Radio>
                  </Radio.Group>
                )}
              </Form.Item>
              <Form.Item label="编码" {...SmallFormItemLayout}>
                {getFieldDecorator('requestEncoding', {
                  initialValue: 'UTF-8',
                  rules: [
                    {
                      required: true,
                      message: '编码不能为空',
                    },
                  ],
                })(<AutoComplete dataSource={['UTF-8', 'GBK']} placeholder="请输入" />)}
              </Form.Item>
            </TabPane>
            <TabPane tab="Header" key="header">
              <DynamicHttpHeaders ref={headersRef} value={httpHeaders} onChange={setHttpHeaders} />
              <Button
                onClick={async () => {
                  try {
                    const headers = await clipboardTextHeaderValues();
                    headersRef.current.resetList(headers);
                  } catch (error) {
                    message.error(error.message);
                  }
                }}
                className="margin-top"
                icon="bg-colors"
                ghost
                type="primary"
              >
                填充Header
              </Button>
            </TabPane>
          </Tabs>
          <div className="ant-detail-title">响应参数</div>
          <Tabs defaultActiveKey="body">
            <TabPane tab="Body" key="body">
              <Form.Item
                label="格式"
                {...{
                  labelCol: { span: 3 },
                  wrapperCol: { span: 9 },
                }}
              >
                {getFieldDecorator('responseBodyFormat', {
                  initialValue: 'JSON',
                  rules: [
                    {
                      required: true,
                      message: '格式不能为空',
                    },
                  ],
                })(
                  <Radio.Group>
                    <Radio value="JSON">JSON</Radio>
                    <Radio value="XML">XML</Radio>
                    <Radio value="NONE">普通文本</Radio>
                    {/* <Radio value="BINARY">二进制</Radio> */}
                  </Radio.Group>
                )}
              </Form.Item>
              <Form.Item label="编码" {...SmallFormItemLayout}>
                {getFieldDecorator('responseEncoding', {
                  initialValue: 'UTF-8',
                })(<AutoComplete dataSource={['UTF-8', 'GBK']} allowClear placeholder="请输入" />)}
              </Form.Item>
            </TabPane>
          </Tabs>
          <div className="ant-detail-title">高级选项</div>
          <Tabs defaultActiveKey="mock">
            <TabPane tab="Mock" key="mock">
              <Row>
                <Col span={12}>
                  <Form.Item label="开启" {...FormItemLayout}>
                    {getFieldDecorator('isMock', {
                      initialValue: false,
                      valuePropName: 'checked',
                    })(<Switch />)}
                  </Form.Item>
                </Col>
              </Row>
              <Row style={{ display: !getFieldValue('isMock') ? 'none' : '' }}>
                <Col span={24}>
                  <Form.Item
                    label="模拟响应"
                    {...{
                      labelCol: { span: 3 },
                      wrapperCol: { span: 21 },
                    }}
                  >
                    {getFieldDecorator('mockResponse')(
                      <TextArea autoSize={{ minRows: 10, maxRows: 10 }} placeholder="请输入" />
                    )}
                  </Form.Item>
                </Col>
              </Row>
            </TabPane>
            <TabPane tab="超时" key="timeout">
              <Row>
                <Col span={10}>
                  <Form.Item label="超时时间" {...FormItemLayout}>
                    {getFieldDecorator('timeoutSeconds', {
                      initialValue: '25',
                    })(<Input placeholder="请输入" suffix="秒" />)}
                  </Form.Item>
                </Col>
                {/* <Col span={14}>
                  <Form.Item label="重试间隔" {...FormItemLayout}>
                    {getFieldDecorator('timeoutRetryIntervalSeconds')(
                      <Input placeholder="请输入" suffix="秒" />
                    )}
                  </Form.Item>
                </Col> */}
              </Row>
            </TabPane>
            <TabPane tab="拦截器" key="interceptor">
              <Row>
                <Col span={12}>
                  <Form.Item label="拦截器处理类" {...FormItemLayout}>
                    {getFieldDecorator('interceptor')(
                      <CustomHandlerSelector
                        getPopupContainer={() => document.getElementById('tg_httpCallEditorForm')}
                        url="/httpCall/listHttpInterceptors"
                      />
                    )}
                  </Form.Item>
                </Col>
              </Row>
            </TabPane>
            <TabPane tab="其他" key="others">
              <Row>
                <Col span={24}>
                  <Form.Item
                    label={
                      <span>
                        替换HTTP数据源响应头&nbsp;
                        <Tooltip title="HTTP调用返回的响应头将会替换掉HTTP数据源的响应头">
                          <Icon type="question-circle-o" />
                        </Tooltip>
                      </span>
                    }
                    {...FormItemLayout}
                  >
                    {getFieldDecorator('replaceResponseHeaders', {
                      initialValue: false,
                      valuePropName: 'checked',
                    })(
                      <Switch
                        onChange={checked =>
                          checked && setFieldsValue({ appendResponseHeaders: false })
                        }
                      />
                    )}
                  </Form.Item>
                </Col>
              </Row>
              <Row>
                <Col span={24}>
                  <Form.Item
                    label={
                      <span>
                        追加HTTP数据源响应头&nbsp;
                        <Tooltip title="HTTP调用返回的响应头将会追加到HTTP数据源的响应头上">
                          <Icon type="question-circle-o" />
                        </Tooltip>
                      </span>
                    }
                    {...FormItemLayout}
                  >
                    {getFieldDecorator('appendResponseHeaders', {
                      initialValue: false,
                      valuePropName: 'checked',
                    })(
                      <Switch
                        onChange={checked =>
                          checked && setFieldsValue({ replaceResponseHeaders: false })
                        }
                      />
                    )}
                  </Form.Item>
                </Col>
              </Row>
              <Row>
                <Col span={24}>
                  <Form.Item
                    label={
                      <span>
                        替换HTTP数据源响应码&nbsp;
                        <Tooltip title="HTTP调用返回的响应码将会替换掉HTTP数据源的响应码">
                          <Icon type="question-circle-o" />
                        </Tooltip>
                      </span>
                    }
                    {...FormItemLayout}
                  >
                    {getFieldDecorator('replaceResponseStatus', {
                      initialValue: false,
                      valuePropName: 'checked',
                    })(<Switch />)}
                  </Form.Item>
                </Col>
              </Row>
            </TabPane>
            {/* <TabPane tab="错误" key="error">
              <Row>
                <Col span={24}>
                  <Form.Item label="4xx/5xx时中断流程" {...FormItemLayout}>
                    {getFieldDecorator('error', {
                      initialValue: true,
                      valuePropName: 'checked',
                    })(<Switch />)}
                  </Form.Item>
                </Col>
              </Row>
            </TabPane> */}
          </Tabs>
        </Form>
      </Spin>
      {renderFooter()}
    </>
  );
}

export default Form.create()(HttpCallEditor);
